package top.jianx.storage.config;


import io.minio.MinioClient;
import io.minio.errors.InvalidEndpointException;
import io.minio.errors.InvalidPortException;
import lombok.AllArgsConstructor;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import top.jianx.storage.factory.StorageTemplateFactory;
import top.jianx.storage.props.StorageProperties;
import top.jianx.storage.rule.StorageRule;
import top.jianx.storage.template.MinioTemplate;
import top.jianx.storage.template.StorageTemplate;
import top.jianx.storage.enums.StorageEnum;

import java.util.HashMap;
import java.util.Map;

@Configuration
@AllArgsConstructor
@EnableConfigurationProperties({StorageProperties.class, StorageRule.class})
@ConditionalOnProperty(value = "spring.storage.name", havingValue = "minio")
public class MinioConfiguration {
    private final StorageProperties properties;
    private final Map<String, StorageRule> rule;


    @Bean
    @ConditionalOnMissingBean(StorageRule.class)
    public StorageRule ossRule() {
        return rule.get("default".equalsIgnoreCase(properties.getStorageRule().getStorageRule())? "defaultStorageRule" : properties.getStorageRule());
    }

    @Bean
    @ConditionalOnMissingBean(MinioClient.class)
    public MinioClient minioClient() throws InvalidPortException, InvalidEndpointException {
        return new MinioClient(properties.getEndpoint(), properties.getAccessKey(), properties.getSecretKey(), false);
    }

    @Bean("minioTemplate")
    @ConditionalOnMissingBean(MinioTemplate.class)
    @ConditionalOnBean({MinioClient.class, StorageRule.class})
    public MinioTemplate minioTemplate(MinioClient minioClient, StorageRule ossRule) {
        return new MinioTemplate(minioClient, properties, ossRule);
    }

    @Bean
    @ConditionalOnMissingBean(StorageTemplateFactory.class)
    @ConditionalOnBean({MinioTemplate.class})
    public StorageTemplateFactory createFactory(MinioTemplate minioTemplate) {
        StorageTemplateFactory factory = new StorageTemplateFactory();
        Map<String, StorageTemplate> templateMap = new HashMap<>(StorageEnum.values().length+1);
        templateMap.put(StorageEnum.MINIO.getStorageType(), minioTemplate);
        factory.setTemplateMap(templateMap);
        return factory;
    }

}
